/***************************************************
> Copyright (C) 2025 ==ASD== All rights reserved.
> File Name: hw4.c
> Author: asd
> Mail:3319941451@qq.com 
> Created Time: 2025年01月06日 星期一 18时22分59秒
***************************************************/
// 服务器端数据管理模块
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <mysql/mysql.h>
#include <unistd.h>
#include <arpa/inet.h>

#include "cJSON.h"
// 数据库连接配置
#define DB_HOST "localhost"
#define DB_USER "root"
#define DB_PASSWORD "Aa123!"
#define DB_NAME "client"

char file_type[20];
char content[1000];


MYSQL *mysql_connection();
int create_sock(const char *ip, unsigned short port);
int sequence_number = 0;
// 接收发送数据信号，发送客户端ID给客户端的函数
void handle_signal_and_send_id() {
    // 创建UDP套接字
    int server_socket = create_sock("127.0.0.1", 6868); 

    // 接收客户端发送的信号
    char buffer[1024];
    int recv_len = recv(server_socket, buffer, sizeof(buffer), 0);
    if (recv_len == -1) 
	{
        perror("接收信号失败");
        close(server_socket);
        exit(EXIT_FAILURE);
    }
	MYSQL *conn = mysql_connection();
	int ret;
	mysql_query(conn, "SET NAMES utf8"); // 设置中文字符集

	char sql_buf[128] = "select * from client";
	ret = mysql_query(conn, sql_buf); // 执行sql语句
	if (ret != 0) {
		printf("mysql query failed\n");
	}
	MYSQL_RES *res;
	MYSQL_ROW row;
	
	res = mysql_store_result(conn); // 存储结果
	char client_id[50];
	memset(&client_id,0,sizeof(client_id));
	for (int i = 0;i < mysql_num_rows(res); i++) 
	{ // 行
		row = mysql_fetch_row(res);
		for (int j = 0;j < mysql_num_fields(res); j++) 
		{
			strcpy(client_id,row[j]);
		}
	}
    // 获取客户端ID并发送给客户端转化成cJSON发给客户端
	char type[20] = {"can_send_ID"};
	cJSON *json = NULL;
	json = cJSON_CreateObject();
		
	cJSON_AddItemToObject(json,"type",cJSON_CreateString(type));
	cJSON_AddItemToObject(json,"client_id",cJSON_CreateString(client_id));
	char *buf = NULL;

	buf = cJSON_Print(json);

	puts(buf);
	ret = send(server_socket, buf, strlen(buf), 0);
    if (ret == -1) 
	{
        perror("发送客户端ID失败");
        close(server_socket);
        exit(EXIT_FAILURE);
    }
	cJSON_Delete(json);
    close(server_socket);
}

// 接收数据并处理的函数
void receive_data_and_authorize() {
    // 创建UDP套接字
   int server_socket = create_sock("127.0.0.1", 6868); 

    // 接收客户端数据
    char buffer[1024];
    struct sockaddr_in client_addr;
    socklen_t client_addr_len = sizeof(client_addr);
    int recv_len = recv(server_socket, buffer, sizeof(buffer), 0);
    if (recv_len == -1) {
        perror("接收数据失败");
        close(server_socket);
        exit(-1);
    }

    // 假设这里提取客户端发送的授权相关信息以及数据
	char type[20];
    char authorization[20];
    char data[1000];
	cJSON *json = NULL;
    cJSON *node = NULL;
    json = cJSON_Parse(buffer);
    node = cJSON_GetObjectItem(json, "type");
    if (node == NULL) 
	{
        printf("can't find\n");
        exit(-1);
    }
	if (node->type == cJSON_String) 
	{
     strcpy(type, node->valuestring);
    }
	if(!strcmp(type,"all_data"))
	{
		printf_data(json);
		node = cJSON_GetObjectItem(json, "authorization");
        if (node == NULL) 
		{
            printf("can't find\n");
            exit(-1);
		}
        if (node->type == cJSON_String) 
		{
            strcpy(authorization, node->valuestring);
        }
	}


    // 将接收到的数据存入文件
    char file_name[50];
    sprintf(file_name, "received_data_%d.txt",sequence_number);
    FILE *fp = fopen(file_name, "wb");
    if (fp == NULL) {
        perror("打开文件失败");
        close(server_socket);
        exit(EXIT_FAILURE);
    }
    fwrite(data, 1, strlen(data), fp);
    fclose(fp);

    // 将授权信息和文件名存入数据库
    MYSQL *conn = mysql_connection();
   

    char query[200];
    sprintf(query, "INSERT INTO authorization (sequence_number,file_name,authorization) VALUES ('%d','%s','%s','%s')", sequence_number,file_type, file_name, authorization);
    if (mysql_query(conn, query)) {
        fprintf(stderr, "数据库插入失败: %s\n", mysql_error(conn));
    }
	
	sequence_number++;
	
    mysql_close(conn);
    close(server_socket);
}

MYSQL *mysql_connection()
{
	MYSQL *conn;

    conn = mysql_init(NULL);
    if (!mysql_real_connect(conn, DB_HOST, DB_USER, DB_PASSWORD, DB_NAME, 0, NULL, 0)) {
        fprintf(stderr, "数据库连接失败: %s\n", mysql_error(conn));
        //close(server_socket);
        exit(EXIT_FAILURE);
    }
	return conn;
}
int create_sock(const char *ip, unsigned short port) 
{
    int server_socket = 0, fd = 0;
    struct sockaddr_in seraddr;
    int ret = 0;
    memset(&seraddr, 0, sizeof(struct sockaddr_in));
    seraddr.sin_family = AF_INET;
    seraddr.sin_addr.s_addr = inet_addr(ip);
    seraddr.sin_port = htons(port);

    server_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (server_socket == -1) {
        perror("socket");
        exit(-1);
    }

    ret = bind(server_socket, (struct sockaddr *)&seraddr, sizeof(struct sockaddr));
    if (ret == -1) {
        perror("bind");
        close(server_socket);
        exit(-1);
    }

    ret = listen(server_socket, 5);
    if (ret == -1) {
        perror("listen");
        close(server_socket);
        exit(-1);
    }
	return server_socket;
}

int main() {
    
    handle_signal_and_send_id();
    receive_data_and_authorize();
    return 0;
}
// 读取信息data（判断数据类型，并进一步解析其中文件类型和内容相关信息）
char *printf_data(cJSON *json)
{
    cJSON *node = NULL;
    node = cJSON_GetObjectItem(json, "data");
    if (node == NULL)
    {
        printf("can't find data\n");
        return;
    }
    else if (node->type == cJSON_String)
    {
        // 将data字段对应的字符串解析为JSON对象，因为其内部还有结构
        cJSON *data_json = cJSON_Parse(node->valuestring);
        if (data_json == NULL)
        {
            printf("Failed to parse data JSON string.\n");
            return;
        }

        cJSON *file_type_node = cJSON_GetObjectItem(data_json, "file_type");
        cJSON *content_node = cJSON_GetObjectItem(data_json, "content");

        if (file_type_node == NULL || content_node == NULL)
        {
            printf("Incomplete data JSON structure.\n");
            cJSON_Delete(data_json);
            return;
        }

        if (file_type_node->type == cJSON_String && content_node->type == cJSON_String)
        {
            printf("文件类型: %s\n", file_type_node->valuestring);
            printf("内容（示例展示，可能是Base64编码等形式的数据）: %s\n", content_node->valuestring);

            // 这里可以根据文件类型做进一步的处理，比如如果是音频，可以调用音频处理相关函数
            // 如果是视频，可以调用视频处理相关函数等，以下是简单示例伪代码
            if (strcmp(file_type_node->valuestring, "text") == 0)
            {
               
            }
            else if (strcmp(file_type_node->valuestring, "video") == 0)
            {
                // 调用视频处理函数，比如解码Base64数据、播放视频等，此处仅为示意
                // video_process(content_node->valuestring);
            }
        }
        else
        {
            printf("Invalid data types in data JSON structure.\n");
        }

        cJSON_Delete(data_json);
    }
}